package com.xjscrm.server.service.groupsendjob.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.OrderItem;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.uzai.mobile.collect.api.enums.MicaMsgSource;
import com.uzai.mobile.collect.api.enums.MicaTalkMsgType;
import com.uzai.trace.TraceGenerate;
import com.xjscrm.common.annotation.MerId;
import com.xjscrm.common.entity.*;
import com.xjscrm.common.enums.RedisCacheKeyEnum;
import com.xjscrm.common.exception.BusinessException;
import com.xjscrm.common.result.ResponseCode;
import com.xjscrm.common.utils.DateUtil;
import com.xjscrm.common.utils.Tools;
import com.xjscrm.common.vo.msg.MsgData;
import com.xjscrm.common.vo.operatorplandevice.OperatorPlanDeviceRule;
import com.xjscrm.server.common.util.DeviceTools;
import com.xjscrm.server.common.util.GroupTools;
import com.xjscrm.server.common.util.SleepTimeTools;
import com.xjscrm.server.dto.groupsendjobmsg.GroupSendJobMsgQuery;
import com.xjscrm.server.dto.groupsendtaskcustomer.GroupSendTaskCustomerQuery;
import com.xjscrm.server.dto.wwcustomer.WwCustomerQuery;
import com.xjscrm.server.dto.wwgroup.WwGroupQuery;
import com.xjscrm.server.mapper.*;
import com.xjscrm.server.req.filterrule.CustomerBasicInfoExcludeFilterReq;
import com.xjscrm.server.req.filterrule.CustomerTagsExcludeFilterReq;
import com.xjscrm.server.req.filterrule.CustomerTimeExcludeFilterReq;
import com.xjscrm.server.service.customer.WwCustomerTagsService;
import com.xjscrm.server.service.filterrule.CustomerCommonFilterService;
import com.xjscrm.server.service.groupsendjob.GroupSendMsgService;
import com.xjscrm.server.service.msg.MsgSendService;
import com.xjscrm.server.vo.device.Device;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * 群发任务异步实现类
 *
 * @author makejava
 * @since 2024-03-01 17:01:12
 */
@Slf4j
@Service
public class GroupSendMsgServiceImpl implements GroupSendMsgService, CustomerCommonFilterService {

    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private GroupSendJobDeviceMapper groupSendJobDeviceMapper;
    @Autowired
    private WwGroupTagsRelationMapper wwGroupTagsRelationMapper;
    @Autowired
    private WwCustomerMapper wwCustomerMapper;
    @Autowired
    private WwGroupMapper wwGroupMapper;
    @Autowired
    private GroupSendJobMsgMapper groupSendJobMsgMapper;
    @Autowired
    private GroupSendTaskCustomerMapper groupSendTaskCustomerMapper;
    @Autowired
    private MsgSendService msgSendService;
    @Autowired
    private WwDeviceMapper wwDeviceMapper;
    @Autowired
    private WwCustomerBlacklistMapper wwCustomerBlacklistMapper;
    @Resource
    private WwCustomerTagsService wwCustomerTagsService;

    /**
     * 添加群发消息
     *
     * @param groupSendJob
     * @return null
     * @author jitwxs
     * @date 2024/3/8 17:12
     */
    @Async("taskExecutorForXxJob")
    @TraceGenerate //注入消息id标签
    public void addGroupSendMsg(@MerId Long merId, GroupSendJob groupSendJob, GroupSendJobDevice groupSendJobDevice) {
        if (groupSendJobDevice == null) {
            throw new BusinessException(ResponseCode.BUSINESS_EXCEPTION, "群发机器人不存在");
        }

        int now = DateUtil.getTime();

        //消息延迟时间
        int delay = 0;

        //是否开启会员发送消息
        Integer customerSwitch = Tools.getInteger(groupSendJob.getCustomerSwitch());
        if (customerSwitch.intValue() == 1) {//开启客户发送消息，则遍历客户表，依次发送消息
            //筛选类型(0-全部客户；1-筛选客户；2-选择客户)
            Integer customerType = Tools.getInteger(groupSendJob.getCustomerType());
            if (customerType.intValue() == 0 || customerType.intValue() == 1) {//需要遍历客户表
                //查询所有的客户
                WwCustomerQuery wwCustomerQuery = new WwCustomerQuery();
                wwCustomerQuery.setMerId(groupSendJob.getMerId());
                wwCustomerQuery.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());

                Page<WwCustomer> page = new Page<>();
                page.setCurrent(1);//只查第一页
                page.setSize(10); //每页查询10个
                page.addOrder(OrderItem.asc("id"));//默认id升序
                Long idStart = 0L;
                List<WwCustomer> wwCustomerList = wwCustomerMapper.findByList(page, wwCustomerQuery);
                while (wwCustomerList != null && wwCustomerList.size() > 0) {
                    for (WwCustomer wwCustomer : wwCustomerList) {
                        try {
                            if (wwCustomer.getId().longValue() >idStart.longValue()) {
                                idStart = wwCustomer.getId();
                            }
                            //客户验证结果，默认为通过验证
                            boolean result = true;
                            if (customerType.intValue() == 1) { //按照条件筛选客户，需要验证
                                result = verifyCustomer(groupSendJob, groupSendJobDevice, wwCustomer, null, 0);
                            }
                            if (result) {//符合条件，则添加消息
                                delay = addMsgData(groupSendJob, groupSendJobDevice, wwCustomer, null, 0, delay);
                            }
                        } catch (Exception e) {
                            log.error(e.getMessage(), e);
                        }
                    }

                    wwCustomerQuery.setIdStart(idStart);
                    wwCustomerList = wwCustomerMapper.findByList(page, wwCustomerQuery);
                }
            } else if (customerType.intValue() == 2) { //选择客户
                //查询选择的客户
                GroupSendTaskCustomerQuery groupSendTaskCustomerQuery = new GroupSendTaskCustomerQuery();
                groupSendTaskCustomerQuery.setMerId(groupSendJob.getMerId());
                groupSendTaskCustomerQuery.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());
                groupSendTaskCustomerQuery.setType(0); //类型（0-私聊;1-群聊）
                groupSendTaskCustomerQuery.setTaskId(groupSendJob.getTaskId());

                Page<GroupSendTaskCustomer> page = new Page<>();
                page.setCurrent(1);//只查第一页
                page.setSize(10); //每页查询10个
                page.addOrder(OrderItem.asc("id"));//默认id升序
                Long idStart = 0L;
                List<GroupSendTaskCustomer> groupSendTaskCustomerList = groupSendTaskCustomerMapper.findByList(page, groupSendTaskCustomerQuery);
                while (groupSendTaskCustomerList != null && groupSendTaskCustomerList.size() > 0) {
                    for (GroupSendTaskCustomer groupSendTaskCustomer : groupSendTaskCustomerList) {
                        try {
                            if (groupSendTaskCustomer.getId().longValue() >idStart.longValue()) {
                                idStart = groupSendTaskCustomer.getId();
                            }

                            //默认黑名单不通过
                            WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(groupSendTaskCustomer.getMerId(), groupSendTaskCustomer.getSendWxid());
                            if(wwCustomerBlacklist != null){ //在黑名单中
                                log.info("黑名单会员wxid={}, merId={}", groupSendTaskCustomer.getSendWxid(), groupSendTaskCustomer.getMerId());
                                continue;
                            }

                            WwCustomer wwCustomer = wwCustomerMapper.queryByDeviceUniqueIdAndWxid(groupSendTaskCustomer.getDeviceUniqueId(), groupSendTaskCustomer.getSendWxid());
                            if (wwCustomer != null) {
                                delay = addMsgData(groupSendJob, groupSendJobDevice, wwCustomer, null, 0, delay);
                            }
                        } catch (Exception e) {
                            log.error("--循环选择客户群发消息失败--error={}", e.getMessage(), e);
                        }
                    }
                    groupSendTaskCustomerQuery.setIdStart(idStart);
                    groupSendTaskCustomerList = groupSendTaskCustomerMapper.findByList(page, groupSendTaskCustomerQuery);
                }
            }
        }

        //是否开启群发送消息
        Integer groupSwitch = Tools.getInteger(groupSendJob.getGroupSwitch());
        if (groupSwitch.intValue() == 1) {//开启群发送消息，则遍历群表，依次发送消息

            //筛选类型(0-全部客户；1-筛选客户；2-选择客户)
            Integer groupType = Tools.getInteger(groupSendJob.getGroupType());
            if (groupType.intValue() == 0 || groupType.intValue() == 1) {//需要遍历群表
                //查询所有的客户
                WwGroupQuery wwGroupQuery = new WwGroupQuery();
                wwGroupQuery.setMerId(groupSendJob.getMerId());
                wwGroupQuery.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());
                Page<WwGroup> page = new Page<>();
                page.setCurrent(1);//只查第一页
                page.setSize(10); //每页查询10个
                page.addOrder(OrderItem.asc("id"));//默认id升序
                Long idStart = 0L;
                List<WwGroup> wwGroupList = wwGroupMapper.findByList(page, wwGroupQuery);
                while (wwGroupList != null && wwGroupList.size() > 0) {
                    for (WwGroup wwGroup : wwGroupList) {
                        try {
                            if (wwGroup.getId().longValue() >idStart.longValue()) {
                                idStart = wwGroup.getId();
                            }

                            //客户验证结果，默认为通过验证
                            boolean result = true;
                            if (groupType.intValue() == 1) { //按照条件筛选客户，需要验证
                                result = verifyCustomer(groupSendJob, groupSendJobDevice, null, wwGroup, 1);
                            }

                            if (result) {//符合条件，则添加消息
                                delay = addMsgData(groupSendJob, groupSendJobDevice, null, wwGroup, 1, delay);
                            }
                        } catch (Exception e) {
                            log.error("--循环所有客户群发消息失败--error={}", e.getMessage(), e);
                        }
                    }

                    wwGroupQuery.setIdStart(idStart);
                    wwGroupList = wwGroupMapper.findByList(page, wwGroupQuery);
                }
            } else if (groupType.intValue() == 2) { //遍历选择的群列表
                //查询选择的客户
                GroupSendTaskCustomerQuery groupSendTaskCustomerQuery = new GroupSendTaskCustomerQuery();
                groupSendTaskCustomerQuery.setMerId(groupSendJob.getMerId());
                groupSendTaskCustomerQuery.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());
                groupSendTaskCustomerQuery.setType(1); //类型（0-私聊;1-群聊）
                groupSendTaskCustomerQuery.setTaskId(groupSendJob.getTaskId());

                Page<GroupSendTaskCustomer> page = new Page<>();
                page.setCurrent(1);//只查第一页
                page.setSize(10); //每页查询10个
                page.addOrder(OrderItem.asc("id"));//默认id升序
                Long idStart = 0L;
                List<GroupSendTaskCustomer> groupSendTaskCustomerList = groupSendTaskCustomerMapper.findByList(page, groupSendTaskCustomerQuery);
                while (groupSendTaskCustomerList != null && groupSendTaskCustomerList.size() > 0) {
                    for (GroupSendTaskCustomer groupSendTaskCustomer : groupSendTaskCustomerList) {
                        try {
                            if (groupSendTaskCustomer.getId().longValue() >idStart.longValue()) {
                                idStart = groupSendTaskCustomer.getId();
                            }

                            WwGroup wwGroup = wwGroupMapper.queryByDeviceUniqueIdAndGroupWxid(groupSendTaskCustomer.getDeviceUniqueId(), groupSendTaskCustomer.getSendWxid());
                            if (wwGroup != null) {
                                delay = addMsgData(groupSendJob, groupSendJobDevice, null, wwGroup, 1, delay);
                            }
                        } catch (Exception e) {
                            log.error("--循环选择的客户群发消息失败--error={}", e.getMessage(), e);
                        }
                    }

                    groupSendTaskCustomerQuery.setIdStart(idStart);
                    groupSendTaskCustomerList = groupSendTaskCustomerMapper.findByList(page, groupSendTaskCustomerQuery);
                }
            }
        }
    }

    /**
     * 验证会员是否符合条件
     *
     * @param wwCustomer 聊天消息
     * @param type       0-客户；1-群
     * @return 实例对象
     */
    private boolean verifyCustomer(GroupSendJob groupSendJob, GroupSendJobDevice groupSendJobDevice, WwCustomer wwCustomer, WwGroup wwGroup, int type) {

        //是否开启群聊开关
        if (type == 1) {//群

            if (wwGroup == null) {
                return false;
            }

            //群wxid
            String groupWxId = Tools.getStr(wwGroup.getGroupWxid());
            String groupName = Tools.getStr(wwGroup.getGroupName());

            //查找此机器人是否在群内成员
//            WwGroupMember wwGroupMember = wwGroupMemberMapper.selectByGroupWxidAndWxid(wwGroup.getMerId(), wwGroup.getGroupWxid(), wwGroup.getDeviceId());
//            if(wwGroupMember == null){
//                return false;
//            }

            //群类型(0-全部客户；1-部分客户)
            Integer groupType = Tools.getInteger(groupSendJob.getGroupType());
            if (groupType.intValue() == 1) { //部分客户，则需要验证条件

                //群名关键词选项(0-含任意关键词；1-含所有关键词)
                Integer groupNameKeywordOpt = groupSendJob.getGroupNameKeywordOpt();
                if (groupNameKeywordOpt != null) {
                    //群名关键词列表
                    List<String> groupNameKeywordList = JSONObject.parseArray(groupSendJob.getGroupNameKeywords(), String.class);
                    if (groupNameKeywordList == null || groupNameKeywordList.size() == 0) { //没有找到，则不回复
                        return false;
                    }

                    if (groupNameKeywordOpt.intValue() == 0) { //满足任意一个
                        boolean groupNameKeywordFlag = false;
                        for (String keyword : groupNameKeywordList) {
                            if (groupName.contains(keyword)) {//找到一个符合的，就返回通过
                                groupNameKeywordFlag = true;
                            }
                        }
                        if (!groupNameKeywordFlag) {
                            return false;
                        }
                    } else {//满足所有触发
                        for (String keyword : groupNameKeywordList) {
                            if (!groupName.contains(keyword)) {//找到一个不符合的，就返回不通过
                                return false;
                            }
                        }
                    }
                }

                //群标签选项(0-含任意标签；1-含所有标签；2-未打任何标签)
                Integer groupTagOpt = groupSendJob.getGroupTagOpt();
                if (groupTagOpt != null) {

                    //封装此群已打的标签
                    List<WwGroupTagsRelation> wwGroupTagsRelationList = wwGroupTagsRelationMapper.selectByDeviceIdAndGroupWxid(groupSendJobDevice.getMerId(), groupSendJobDevice.getDeviceId(), groupWxId);
                    List<Long> wwGroupTagedList = new ArrayList<>();
                    if (wwGroupTagsRelationList != null && wwGroupTagsRelationList.size() > 0) {
                        for (WwGroupTagsRelation wwGroupTagsRelation : wwGroupTagsRelationList) {
                            wwGroupTagedList.add(wwGroupTagsRelation.getTagId());
                        }
                    }

                    //2-未打任何标签
                    if (groupTagOpt.intValue() == 2) {
                        if (wwGroupTagedList.size() > 0) {
                            return false;
                        }
                    } else {
                        //标签列表
                        List<Long> groupTagList = JSONObject.parseArray(groupSendJob.getGroupTags(), Long.class);
                        if (groupTagList == null || groupTagList.size() == 0) { //没有找到，则不回复
                            return false;
                        }
                        if (groupTagOpt.intValue() == 0) { //满足任意一个
                            boolean tagFlag = false;
                            for (Long groupTag : groupTagList) {
                                if (wwGroupTagedList.contains(groupTag)) {//找到一个符合的，就返回通过
                                    tagFlag = true;
                                    break;
                                }
                            }
                            if (!tagFlag) {
                                return false;
                            }
                        } else if (groupTagOpt.intValue() == 1) {//满足所有触发
                            if (!wwGroupTagedList.containsAll(groupTagList)) {
                                return false;
                            }
                        }
                    }
                }

                //群成员角色列表(0-群主；1-管理员；2-普通成员)
                String  groupMemberIdentitys = groupSendJob.getGroupMemberIdentitys();
                List<Integer> groupMemberIdentityList = JSONObject.parseArray( groupMemberIdentitys, Integer.class);
                if (groupMemberIdentityList != null && groupMemberIdentityList.size() > 0) {
                    boolean identityFlag = GroupTools.verifyIdentity(wwGroup, groupMemberIdentityList, groupSendJobDevice.getDeviceId());
                    if (!identityFlag) {
                        return false;
                    }
                }

                //验证群人数
                Integer groupMemberTotalMin = groupSendJob.getGroupMemberTotalMin();
                Integer groupMemberTotalMax = groupSendJob.getGroupMemberTotalMax();
                if (groupMemberTotalMin != null
                        && groupMemberTotalMax != null
                        && groupMemberTotalMin.intValue() <= groupMemberTotalMin.intValue()
                ) {
                    //在群人数
                    String groupMemberCountKey = String.format(RedisCacheKeyEnum.GROUP_MEMBER_COUNT.getKey(), groupWxId);
                    Integer groupMemberCount =  (Integer)redisTemplate.opsForValue().get(groupMemberCountKey);
                    Integer memberTotal = Tools.getInteger(groupMemberCount);
                    if (memberTotal.intValue() < groupMemberTotalMin.intValue()
                            || memberTotal.intValue() > groupMemberTotalMax.intValue()
                    ) {
                        return false;
                    }
                }

                //验证建群时间
                String groupCreateDayStart = groupSendJob.getGroupCreateDayStart();
                String groupCreateDayEnd = groupSendJob.getGroupCreateDayEnd();
                if (StringUtils.isNotBlank(groupCreateDayStart)
                        && StringUtils.isNotBlank(groupCreateDayEnd)
                ) {
                    Integer groupCreateTime = wwGroup.getGroupCreateTime();
                    if (groupCreateTime == null) {//如果没有建群时间，则不通过
                        return false;
                    }
                    //判断旧发送时间是否在允许区间内
                    Instant instant_groupCreateTime = Instant.ofEpochMilli(groupCreateTime * 1000L);
                    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant_groupCreateTime, ZoneId.systemDefault());
                    boolean withinTimeInterval_groupCreateTime = Tools.isWithinDateInterval(localDateTime, LocalDate.parse(groupCreateDayStart), LocalDate.parse(groupCreateDayEnd));
                    if (!withinTimeInterval_groupCreateTime) {
                        return false;
                    }
                }
            }
        } else {//会员
            if (wwCustomer == null) {
                return false;
            }

            //是否开启群聊开关
            Integer customerSwitch = Tools.getInteger(groupSendJob.getCustomerSwitch());
            if (customerSwitch.intValue() == 0) { //不开启客户消息，直接不通过
                return false;
            }

            //默认黑名单不通过
            WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(groupSendJob.getMerId(), wwCustomer.getWxid());
            if(wwCustomerBlacklist != null){ //在黑名单中
                log.info("黑名单会员wxid={}, merId={}", wwCustomer.getWxid(), wwCustomer.getMerId());
                return false;
            }

            //客户类型(0-全部客户；1-部分客户)
            Integer customerType = Tools.getInteger(groupSendJob.getCustomerType());
            if (customerType.intValue() == 1) { //部分客户，则需要验证条件
                //获取客户已打的标签
                List<Long> wwCustomerTagedList = wwCustomerTagsService.getTagIds(wwCustomer.getMerId(), wwCustomer.getId());
                CustomerTagsExcludeFilterReq customerTagsExcludeFilterReq = new CustomerTagsExcludeFilterReq(groupSendJob.getExcludeCustomerEnterpriseTagOpt(), groupSendJob.getExcludeCustomerEnterpriseTags(), wwCustomerTagedList, groupSendJob.getOpenExclude());
                CustomerTimeExcludeFilterReq customerTimeExcludeFilterReq = new CustomerTimeExcludeFilterReq(groupSendJob.getExcludeNewCustomer(), wwCustomer.getCreateTime(), groupSendJob.getExcludeCustomerCreateDayStart(), groupSendJob.getExcludeCustomerCreateDayEnd(), groupSendJob.getOpenExclude());
                CustomerBasicInfoExcludeFilterReq customerBasicInfoExcludeFilterReq = new CustomerBasicInfoExcludeFilterReq(wwCustomer, groupSendJob.getExcludeCustomerRemarkOpt(), groupSendJob.getExcludeCustomerGenders(), groupSendJob.getOpenExclude());
                if (this.excludeFilter(customerTagsExcludeFilterReq, customerTimeExcludeFilterReq, customerBasicInfoExcludeFilterReq)) {
                    return false;
                }
                //客户企业标签选项(0-含任意标签；1-含所有标签；2-未打任何标签)
                Integer customerEnterpriseTagOpt = groupSendJob.getCustomerEnterpriseTagOpt();
                if (customerEnterpriseTagOpt != null) {
                    //2-未打任何标签
                    if (customerEnterpriseTagOpt.intValue() == 2) {
                        if (wwCustomerTagedList.size() > 0) {
                            return false;
                        }
                    } else {
                        //标签列表
                        List<Long> customerEnterpriseTagList = JSONObject.parseArray(groupSendJob.getCustomerEnterpriseTags(), Long.class);
                        if (customerEnterpriseTagList == null || customerEnterpriseTagList.size() == 0) { //没有找到，则不回复
                            return false;
                        }
                        if (customerEnterpriseTagOpt.intValue() == 0) { //满足任意一个
                            boolean tagFlag = false;
                            for (Long customerEnterpriseTag : customerEnterpriseTagList) {
                                if (wwCustomerTagedList.contains(customerEnterpriseTag)) {//找到一个符合的，就返回通过
                                    tagFlag = true;
                                    break;
                                }
                            }
                            if (!tagFlag) {
                                return false;
                            }
                        } else if (customerEnterpriseTagOpt.intValue() == 1) {//满足所有触发
                            if (!wwCustomerTagedList.containsAll(customerEnterpriseTagList)) {
                                return false;
                            }
                        }
                    }
                }

                //加好友时间
                String customerCreateDayStart = groupSendJob.getCustomerCreateDayStart();
                String customerCreateDayEnd = groupSendJob.getCustomerCreateDayEnd();
                if (StringUtils.isNotBlank(customerCreateDayStart)
                        && StringUtils.isNotBlank(customerCreateDayEnd)
                ) {
                    Integer customerCreateTime = wwCustomer.getCreateTime();
                    if (customerCreateTime == null) {//如果没有添加好友时间，则不通过
                        return false;
                    }
                    //判断旧发送时间是否在允许区间内
                    Instant instant_groupCreateTime = Instant.ofEpochMilli(customerCreateTime * 1000L);
                    LocalDateTime localDateTime = LocalDateTime.ofInstant(instant_groupCreateTime, ZoneId.systemDefault());
                    boolean withinTimeInterval_customerCreateTime = Tools.isWithinDateInterval(localDateTime, LocalDate.parse(customerCreateDayStart), LocalDate.parse(customerCreateDayEnd));
                    if (!withinTimeInterval_customerCreateTime) {
                        return false;
                    }
                }

                //客户备注选项(0-无备注；1-有备注)
                Integer customerRemarkOpt = groupSendJob.getCustomerRemarkOpt();
                if (customerRemarkOpt != null) {
                    if (customerRemarkOpt.intValue() == 0) {//无备注
                        if (StringUtils.isNotBlank(wwCustomer.getRemark())) {
                            return false;
                        }
                    } else if (customerRemarkOpt.intValue() == 1) { //有备注
                        if (StringUtils.isBlank(wwCustomer.getRemark())) {
                            return false;
                        }
                    }
                }

                //性别(0-未知；1-男；2-女)
                Integer customerGenders = groupSendJob.getCustomerGenders();
                if (customerGenders != null) {
                    //验证客户性别是否跟配置的符合
                    if (customerGenders.intValue() != Tools.getInteger(wwCustomer.getGender()).intValue()) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * 封装消息
     *
     * @param groupSendJob
     * @param groupSendJobDevice
     * @param wwCustomer
     * @param wwGroup
     * @param type               类型（0-私聊;1-群聊）
     * @return int
     * @author jitwxs
     * @date 2024/4/1 18:52
     */
    public int addMsgData(GroupSendJob groupSendJob, GroupSendJobDevice groupSendJobDevice, WwCustomer wwCustomer, WwGroup wwGroup, int type, int delay) {

        String msgDatas = groupSendJob.getMsgDatas();
        if (StringUtils.isBlank(msgDatas)) {
            return delay;
        }

        String sendWxid = null;
        String sendNickname = null;

        if (type == 1) {//群聊
            if (wwGroup != null) {
                sendWxid = wwGroup.getGroupWxid();
            }
        } else {//私聊
            if (wwCustomer != null) {
                sendWxid = wwCustomer.getWxid();
                //替换[称呼/昵称]变量，优先称呼，在昵称
                sendNickname = wwCustomer.getNickname();
                if (StringUtils.isBlank(sendNickname)) {
                    sendNickname = wwCustomer.getName();
                }
            }
        }

        if (StringUtils.isBlank(sendWxid)) {
            return delay;
        }

        List<MsgData> msgDataList = JSONObject.parseArray(msgDatas, MsgData.class);
        if (msgDataList == null || msgDataList.size() == 0) {
            return delay;
        }

        //每个会员的间隔时间
        Integer rateMin = Tools.getInteger(groupSendJobDevice.getRateMin());
        Integer rateMax = Tools.getInteger(groupSendJobDevice.getRateMax());
        int randomRate = SleepTimeTools.randomRate(rateMin, rateMax);
        delay = delay + randomRate; //累加每个会员间隔时间

        for (MsgData msgData : msgDataList) {
            delay = delay + Tools.getInteger(msgData.getGap()) * Tools.getInteger(msgData.getUnit());
            //计算此时机器人是否休眠，如果休眠，则需要跳过这段休眠时间
            OperatorPlanDeviceRule operatorPlanDeviceRule = JSONObject.parseObject(groupSendJobDevice.getRule(), OperatorPlanDeviceRule.class);
            int sleepTimeDelay = SleepTimeTools.getSleepTimeDelay(operatorPlanDeviceRule, delay, groupSendJob.getStartSendTime());
            GroupSendJobMsg groupSendJobMsg = new GroupSendJobMsg();
            groupSendJobMsg.setId(IdWorker.getId());
            groupSendJobMsg.setMerId(groupSendJobDevice.getMerId());
            groupSendJobMsg.setJobId(groupSendJobDevice.getJobId());
            groupSendJobMsg.setStatus(1); //未发送
            groupSendJobMsg.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());
            groupSendJobMsg.setType(type);
            groupSendJobMsg.setSendWxid(sendWxid);

            //替换[称呼/昵称]变量，优先称呼，在昵称
            if (msgData.getMsgType().intValue() == MicaTalkMsgType.TEXT.getCode().intValue()) {//文本消息
                String content = Tools.getStr(msgData.getContent());
                content = content.replace("[称呼/昵称]", Tools.getStr(sendNickname));
                msgData.setContent(content);
            }
            groupSendJobMsg.setMsgData(JSONObject.toJSONString(msgData));
            groupSendJobMsg.setDelay(delay);
            groupSendJobMsg.setCreateTime(groupSendJobDevice.getCreateTime());
            groupSendJobMsg.setUpdateTime(groupSendJobDevice.getCreateTime());
            groupSendJobMsgMapper.insertSelective(groupSendJobMsg);
        }

        return delay;
    }

    /**
     * 将群发消息封装到MQ
     * @param merId
     * @return null
     * @author jitwxs
     * @date 2024/3/8 17:12
     */
    @Async("taskExecutorForXxJob")
    @TraceGenerate //注入消息id标签
    public void groupSendJobMsgToMqSync(@MerId Long merId, GroupSendJob groupSendJob, GroupSendJobDevice groupSendJobDevice){
        //限流key
        String taskLimitKey = "-groupSendJobMsgToMqSync-taskLimitKey-groupSendJobDeviceId=" + groupSendJobDevice.getId();
        Object object = redisTemplate.opsForValue().get(taskLimitKey);
        if (object != null) {
            return;
        }

        //封装MQ
        WwDevice wwDevice = wwDeviceMapper.queryById(groupSendJobDevice.getDeviceUniqueId());
        if(wwDevice == null) {
            return;
        }
        Device device = DeviceTools.transDevice(wwDevice);

        //保存限流key
        redisTemplate.opsForValue().set(taskLimitKey, groupSendJobDevice.getId(), 100, TimeUnit.SECONDS);

        log.info("-----将群发消息封装到MQ----merId=" + merId);

        try {
            //查询该机器人任务的延迟快照时间
            Integer delaySnapshot = Tools.getInteger(groupSendJobDevice.getDelaySnapshot());

            //查询当前所有开启的自动发圈的配置方案
            int now = DateUtil.getTime();
            int startSendTime = Tools.getInteger(groupSendJob.getStartSendTime()).intValue();
            //计算当前时间和开始发送时间之前的差值
            int dif_now_startSendTime = now - startSendTime;

            GroupSendJobMsgQuery groupSendJobMsgQuery = new GroupSendJobMsgQuery();
            groupSendJobMsgQuery.setMerId(merId);
            groupSendJobMsgQuery.setDeviceUniqueId(groupSendJobDevice.getDeviceUniqueId());
            groupSendJobMsgQuery.setJobId(groupSendJobDevice.getJobId());
            groupSendJobMsgQuery.setDelayEnd(dif_now_startSendTime + 30); //30秒内的所有消息插入到mq当中
            groupSendJobMsgQuery.setStatus(1); //状态（1-未发送；2-已发送；3-发送失败)

            //查询所有的自动发圈配置记录
            Page<GroupSendJobMsg> page = new Page<>();
            page.setCurrent(1);//只查第一页
            page.setSize(10); //每页查询10个
            page.addOrder(OrderItem.asc("id"));//默认id升序
            Long idStart = 0L;
            List<GroupSendJobMsg> groupSendJobMsgList = groupSendJobMsgMapper.findByList(page, groupSendJobMsgQuery);
            if (groupSendJobMsgList != null && groupSendJobMsgList.size() > 0) {
                for (GroupSendJobMsg groupSendJobMsg : groupSendJobMsgList) {
                    if (groupSendJobMsg.getId().longValue() >idStart.longValue()) {
                        idStart = groupSendJobMsg.getId();
                    }

                    //限流判断
                    String rateLimitKey = "groupSendJobMsgToMqSync-msgId=" + groupSendJobMsg.getId();
                    Object rateLimitKeyObject = redisTemplate.opsForValue().get(rateLimitKey);
                    if(rateLimitKeyObject == null){
                        redisTemplate.opsForValue().set(rateLimitKey, rateLimitKey, 300, TimeUnit.SECONDS);
                    } else{
                        continue;
                    }

                    try {

                        if(Tools.getInteger(groupSendJobMsg.getDelay()).intValue() > delaySnapshot.intValue()){
                            delaySnapshot = Tools.getInteger(groupSendJobMsg.getDelay());
                        }

                        //私聊，验证是否是黑名单
                        if(groupSendJobMsg.getType().intValue() == 0){
                            //默认黑名单不通过
                            WwCustomerBlacklist wwCustomerBlacklist = wwCustomerBlacklistMapper.selectByWxid(groupSendJobMsg.getMerId(), groupSendJobMsg.getSendWxid());
                            if(wwCustomerBlacklist != null){ //在黑名单中
                                log.info("黑名单会员wxid={}, merId={}", groupSendJobMsg.getSendWxid(), groupSendJobMsg.getMerId());
                                //处理群发任务
                                groupSendJobMsg.setStatus(3); //状态（1-未发送；2-已发送；3-发送失败)
                                groupSendJobMsg.setUpdateTime(DateUtil.getTime());
                                groupSendJobMsgMapper.updateStatusById(groupSendJobMsg);
                                continue;
                            }
                        }

                        //处理群发任务
                        groupSendJobMsg.setStatus(2); //状态（1-未发送；2-已发送；3-发送失败)
                        groupSendJobMsg.setUpdateTime(DateUtil.getTime());
                        groupSendJobMsgMapper.updateStatusById(groupSendJobMsg);

                        MsgData msgData = JSONObject.parseObject(groupSendJobMsg.getMsgData(), MsgData.class);
                        if(msgData != null){
                            msgData.setGap(groupSendJobMsg.getDelay());
                            msgData.setUnit(1); //秒
                        }
                        //判断是否是群发
                        boolean group = false;
                        if(Tools.getInteger(groupSendJobMsg.getType()) == 1){
                            group = true;
                        }
                        msgSendService.msgSend(device, groupSendJobMsg.getSendWxid(), null, msgData, false, null, dif_now_startSendTime, MicaMsgSource.GROUP_SEND.getCode(), group);
                    } catch (Exception e) {
                        log.error("--封装群发消息失败--error={}", e.getMessage(), e);
                    }finally {
                        //保存成功之后，手动删除限流redisKey
                        redisTemplate.delete(rateLimitKey);
                    }
                }

                //修改子任务的延迟快照时间
                groupSendJobDevice.setDelaySnapshot(delaySnapshot);
                groupSendJobDeviceMapper.updateDelaySnapshotById(groupSendJobDevice);

//                groupSendJobMsgQuery.setIdStart(idStart);
//                groupSendJobMsgList = groupSendJobMsgMapper.findByList(page, groupSendJobMsgQuery);
            }
        } catch (Exception e) {
            log.info(e.getMessage(),e);
        } finally {
            //删除限流key
            redisTemplate.delete(taskLimitKey);
        }

    }


}
